package cn.cangfei.massage.service.impl;

import cn.cangfei.massage.dto.param.VisitProductParamDto;
import cn.cangfei.massage.dto.param.VisitProductQueryParam;
import cn.cangfei.massage.dto.update.VisitProductInfo;
import cn.cangfei.massage.entity.MassageProduct;
import cn.cangfei.massage.entity.UserBasicInfo;
import cn.cangfei.massage.entity.UserBasicInfoExample;
import cn.cangfei.massage.entity.VisitProduct;
import cn.cangfei.massage.mapper.MassageProductMapper;
import cn.cangfei.massage.mapper.UserBasicInfoMapper;
import cn.cangfei.massage.mapper.VisitProductMapper;
import cn.cangfei.massage.service.IUserBasicInfoService;
import cn.cangfei.massage.service.IVisitProductService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class VisitProductServiceImpl extends ServiceImpl<VisitProductMapper, VisitProduct> implements IVisitProductService {

    @Resource
    private IUserBasicInfoService userBasicInfoService;

    @Resource
    private MassageProductMapper massageProductMapper;

    @Resource
    private UserBasicInfoMapper userBasicInfoMapper;

    /**
     * 判断这个产品是否存在
     *
     * @param productId
     * @return
     */
    @Override
    public boolean countProductId(Long productId) {
        MassageProduct massageProduct = massageProductMapper.selectById(productId);
        return massageProduct == null;
    }

    /**
     * 添加预约产品信息
     *
     * @param openId
     * @param productId
     * @return
     */
    @Override
    public String insert(String openId, Long productId, Integer buycount) {

        // 先查询
        LambdaQueryWrapper<MassageProduct> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(MassageProduct::getId, productId);
        MassageProduct massageProduct = massageProductMapper.selectOne(lambdaQueryWrapper);
        Integer buycount1 = massageProduct.getBuycount();
        if (buycount > buycount1) {
            throw new RuntimeException("一次性最多只能预约" + buycount1 + "个产品");
        }

        // 先判断是否预约过这个产品
        // 如果预约了过了直接返回
        UserBasicInfo user = userBasicInfoService.getUserByOpenId(openId);
        Long userId = user.getId();
        LambdaQueryWrapper<VisitProduct> visitProductLambdaQueryWrapper = new LambdaQueryWrapper<>();
        visitProductLambdaQueryWrapper.eq(VisitProduct::getUserId, userId);
        visitProductLambdaQueryWrapper.eq(VisitProduct::getProductId, productId);
        // 你预约了但是没有去买东西，就不能在预约了
        visitProductLambdaQueryWrapper.eq(VisitProduct::getOk, 0);

        // 0表示他预约了但是没有去买东西，就不能在预约了
        VisitProduct one = getOne(visitProductLambdaQueryWrapper);
        if (one != null) {
            return "1";
        }

        VisitProduct visitProduct = new VisitProduct();

        visitProduct.setUserId(userId);
        visitProduct.setProductId(productId);
        visitProduct.setOk(0); // 最开始都是只是预约了
        visitProduct.setBuycount(buycount);

        return save(visitProduct) ? "0" : "2";
    }

    /**
     * 查看和这个预约编号是否存在
     *
     * @param id
     * @return
     */
    @Override
    public boolean countId(Long id) {
        VisitProduct visitProduct = getById(id);
        return visitProduct == null;
    }

    /**
     * 删除预约产品的信息
     *
     * @param id
     * @return
     */
    @Override
    public boolean deleteAppointmentProduct(Long id) {
        return removeById(id);
    }

    /**
     * 完成预约产品详细信息
     *
     * @param id
     * @return
     */
    @Override
    public boolean AppointmentProductOk(Long id) {

        VisitProduct visitProduct = getById(id);
        // 已经处理过了
        if (visitProduct.getOk() == 1) {
            return true;
        }
        visitProduct.setOk(1);
        return updateById(visitProduct);
    }

    /**
     * 查询预约产品信息
     *
     * @param id
     * @return
     */
    @Override
    public VisitProductInfo getAppointmentProductInfo(Long id) {
        VisitProduct visitProduct = getById(id);
        Long productId = visitProduct.getProductId();
        Long userId = visitProduct.getUserId();

        VisitProductInfo visitProductInfo = new VisitProductInfo();


        // 首先是获得产品信息
        MassageProduct massageProduct = massageProductMapper.selectById(productId);
        BeanUtils.copyProperties(massageProduct, visitProductInfo);
        visitProductInfo.setProductName(massageProduct.getName());

        // 其次获得用户信息
        UserBasicInfo userBasicInfo = userBasicInfoMapper.selectByPrimaryKey(userId);
        BeanUtils.copyProperties(userBasicInfo, visitProductInfo);

        // 预约的时间
        Date gmtCreate = visitProduct.getGmtCreate();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = simpleDateFormat.format(gmtCreate);
        visitProductInfo.setGmtCreate(format);
        visitProductInfo.setId(id);

        return visitProductInfo;
    }

    /**
     * 分页查询产品信息
     *
     * @param productName
     * @param userName
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public IPage<VisitProductParamDto> list(String productName, String userName, Integer pageNum, Integer pageSize) {

        IPage<VisitProductParamDto> dtoIPage = new Page<>(pageNum, pageSize);

        IPage<VisitProduct> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<VisitProduct> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        IPage<VisitProduct> page1 = page(page, lambdaQueryWrapper);

        List<VisitProduct> records = page1.getRecords();
        if (records == null) {
            BeanUtils.copyProperties(page1, dtoIPage);
            return dtoIPage;
        }


        // 给里面每一个进行赋值records

        // 最后要返回的前一个
        List<VisitProductParamDto> collect = records.stream().map(item -> {
            VisitProductParamDto visitProductParamDto = new VisitProductParamDto();
            BeanUtils.copyProperties(item, visitProductParamDto);
            visitProductParamDto.setBuycount(item.getBuycount());
            return visitProductParamDto;
        }).collect(Collectors.toList());


        // 得到每一个产品
        // 如果没有产品了表示原来是有的，但是删除了
        List<MassageProduct> massageProducts = massageProductMapper.selectList(null);


        // 得到每一个用户
        UserBasicInfoExample userBasicInfoExample = new UserBasicInfoExample();
        List<UserBasicInfo> userBasicInfos = userBasicInfoMapper.selectByExample(userBasicInfoExample);

        collect.forEach(item -> {
            if (massageProducts != null) {
                // 得到产品信息
                for (MassageProduct i1 : massageProducts) {
                    if (Objects.equals(item.getProductId(), i1.getId())) {
                        item.setProductName(i1.getName());
                        item.setPrice(i1.getPrice());
                        item.setDescription(i1.getDescription());
                        break;
                    }

                }
            }
            if (userBasicInfos != null) {
                //
                for (UserBasicInfo u1 : userBasicInfos) {
                    if (Objects.equals(item.getUserId(), u1.getId())) {
                        item.setUserName(u1.getName());
                        break;
                    }
                }
            }
        });

        // 这个collect是收集到的
        // 下面开始条件查询
        LambdaQueryWrapper<MassageProduct> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();


        if (!"".equals(productName)) {
            lambdaQueryWrapper1.like(MassageProduct::getName, productName);

            List<MassageProduct> massageProducts1 = massageProductMapper.selectList(lambdaQueryWrapper1);
            // 得到所有的id
            if (massageProducts1 != null) {
                // 返回产品id
                List<Long> longStream = massageProducts1.stream().map(MassageProduct::getId).collect(Collectors.toList());
                collect = collect.stream().filter(item -> {
                    // 返回包含的
                    return longStream.contains(item.getProductId());
                }).collect(Collectors.toList());
            }
        }

        UserBasicInfoExample.Criteria basicInfoExampleCriteria = userBasicInfoExample.createCriteria();
        if (!"".equals(userName)) {
            basicInfoExampleCriteria.andNameLike(userName);
            List<UserBasicInfo> userBasicInfos1 = userBasicInfoMapper.selectByExample(userBasicInfoExample);
            if (userBasicInfos1 != null) {
                List<Long> collected = userBasicInfos1.stream().map(UserBasicInfo::getId).collect(Collectors.toList());
                collect = collect.stream().filter(item -> {
                    // 返回包含的
                    return collected.contains(item.getUserId());
                }).collect(Collectors.toList());
            }
        }
        dtoIPage.setTotal(collect.size());
        dtoIPage.setRecords(collect);
        return dtoIPage;
    }

    /**
     * 获取预约列表信息小程序端
     *
     * @param openId
     * @return
     */
    @Override
    public IPage<VisitProductParamDto> getAppointmentListProductInfoByUserId(String openId) {
        UserBasicInfo user = userBasicInfoService.getUserByOpenId(openId);

        IPage<VisitProductParamDto> dtoIPage = new Page<>(1, 100);
        IPage<VisitProduct> page = new Page<>(1, 100);
        LambdaQueryWrapper<VisitProduct> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 降序排序
        lambdaQueryWrapper.orderByDesc(VisitProduct::getGmtCreate);
        lambdaQueryWrapper.eq(VisitProduct::getUserId, user.getId());
        page = page(page, lambdaQueryWrapper);

        List<VisitProduct> records = page.getRecords();
        BeanUtils.copyProperties(page, dtoIPage);
        if (records == null) {
            // 表示没有预约信息
            return dtoIPage;
        }

        List<VisitProductParamDto> collect = records.stream().map(item -> {
            VisitProductParamDto visitProductParamDto = new VisitProductParamDto();
            BeanUtils.copyProperties(item, visitProductParamDto);
            // 这是预约的数量
            visitProductParamDto.setBuycount(item.getBuycount());
            return visitProductParamDto;
        }).collect(Collectors.toList());

        // 下面开始赋值
        // 给上产品信息以及
        // 得到每一个产品
        // 如果没有产品了表示原来是有的，但是删除了
        List<MassageProduct> massageProducts = massageProductMapper.selectList(null);


        // 有预约记录的话
        collect.forEach(item -> {
            if (massageProducts != null) {
                // 得到产品信息
                for (MassageProduct i1 : massageProducts) {
                    if (Objects.equals(item.getProductId(), i1.getId())) {
                        item.setProductName(i1.getName());
                        item.setPrice(i1.getPrice());
                        item.setDescription(i1.getDescription());
                        break;
                    }

                }
            }
        });
        dtoIPage.setRecords(collect);
        return dtoIPage;
    }

    /**
     * 取消预约产品
     *
     * @param id
     * @return
     */
    @Override
    public boolean AppointmentProductCancel(Long id) {
        VisitProduct visitProduct = getById(id);
        // 已经处理过了
        if (visitProduct.getOk() == 2) {
            return true;
        }
        visitProduct.setOk(2);
        return updateById(visitProduct);
    }

    /**
     * 获取预约列表信息后台管理系统
     *
     * @param param
     * @return
     */
    @Override
    public IPage<VisitProductParamDto> getAppointmentListProductInfo(VisitProductQueryParam param, Integer pageNum, Integer pageSize) {
        IPage<VisitProductParamDto> dtoIPage = new Page<>(pageNum, pageSize);
        IPage<VisitProduct> page = new Page<>(pageNum, pageSize);

        String userName = param.getUserName();
        String productName = param.getProductName();
        Integer status = param.getStatus();
        LambdaQueryWrapper<MassageProduct> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();

        List<Long> userIdList = new ArrayList<>();
        UserBasicInfoExample userBasicInfoExample = new UserBasicInfoExample();

        if (userName != null && !"".equals(userName)) {
            userBasicInfoExample.createCriteria().andNameLike("%" + userName + "%");
        }
        List<UserBasicInfo> userBasicInfos = userBasicInfoMapper.selectByExample(userBasicInfoExample);

        if (userBasicInfos == null || userBasicInfos.size() == 0) {
            return dtoIPage;
        }

        // 得到userId
        userIdList = userBasicInfos.stream().map(UserBasicInfo::getId).collect(Collectors.toList());

        List<Long> productIdList = new ArrayList<>();
        if (productName != null && !"".equals(productName)) {
            lambdaQueryWrapper1.like(MassageProduct::getName, productName);

        }

        List<MassageProduct> massageProducts = massageProductMapper.selectList(lambdaQueryWrapper1);

        if (massageProducts == null || massageProducts.size() == 0) {
            return dtoIPage;
        }


        productIdList = massageProducts.stream().map(MassageProduct::getId).collect(Collectors.toList());
        LambdaQueryWrapper<VisitProduct> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 降序排序
        lambdaQueryWrapper.orderByDesc(VisitProduct::getGmtCreate);
        if (userIdList.size() > 0) {
            lambdaQueryWrapper.in(VisitProduct::getUserId, userIdList);
        }
        if (productIdList.size() > 0) {
            lambdaQueryWrapper.in(VisitProduct::getProductId, productIdList);
        }
        if (status != null) {
            lambdaQueryWrapper.eq(VisitProduct::getOk, status);
        }

        page = page(page, lambdaQueryWrapper);

        List<VisitProduct> records = page.getRecords();
        BeanUtils.copyProperties(page, dtoIPage);
        if (records == null) {
            // 表示没有预约信息
            return dtoIPage;
        }

        List<VisitProductParamDto> collect = records.stream().map(item -> {
            VisitProductParamDto visitProductParamDto = new VisitProductParamDto();
            BeanUtils.copyProperties(item, visitProductParamDto);
            return visitProductParamDto;
        }).collect(Collectors.toList());

        // 下面开始赋值
        // 给上产品信息以及
        // 得到每一个产品
        // 如果没有产品了表示原来是有的，但是删除了
        List<MassageProduct> massageProducts1 = massageProductMapper.selectList(null);


        UserBasicInfoExample userBasicInfoExample1 = new UserBasicInfoExample();
        List<UserBasicInfo> userBasicInfos1 = userBasicInfoMapper.selectByExample(userBasicInfoExample1);
        // 有预约记录的话
        collect.forEach(item -> {
            if (massageProducts1 != null && massageProducts1.size() > 0) {
                // 得到产品信息
                for (MassageProduct i1 : massageProducts1) {
                    if (Objects.equals(item.getProductId(), i1.getId())) {
                        item.setProductName(i1.getName());
                        item.setPrice(i1.getPrice());
                        item.setDescription(i1.getDescription());
                        break;
                    }

                }

            }

            if (userBasicInfos1 != null && userBasicInfos1.size() > 0) {
                // 设置用户姓名
                for (UserBasicInfo userBasicInfo : userBasicInfos1) {
                    if (Objects.equals(item.getUserId(), userBasicInfo.getId())) {
                        item.setUserName(userBasicInfo.getChild());
                        item.setPhone(userBasicInfo.getPhone());
                        break;
                    }
                }


            }
        });
        dtoIPage.setRecords(collect);
        return dtoIPage;
    }

    /**
     * 修改预约的数量
     *
     * @param openId
     * @param productId
     * @param buycount
     * @return
     */
    @Override
    public Boolean updateAppointmentProduct(String openId, Long productId, Integer buycount) {
        UserBasicInfo user = userBasicInfoService.getUserByOpenId(openId);
        if (user == null) {
            return false;
        }
        Long userId = user.getId();
        LambdaUpdateWrapper<VisitProduct> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(VisitProduct::getUserId, userId);
        lambdaUpdateWrapper.eq(VisitProduct::getProductId, productId);
        lambdaUpdateWrapper.eq(VisitProduct::getOk, 0); // 表示没有预约了还没有去完成
        lambdaUpdateWrapper.set(VisitProduct::getBuycount, buycount);
        boolean update = update(lambdaUpdateWrapper);
        return update;
    }

    /**
     * 批量删除预约记录
     *
     * @param type
     * @return
     */
    @Transactional
    @Override
    public boolean deleteAppointmentProducts(Integer type) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("当前时间" + df.format(new Date()));

        int month = 0;
        if (type == 1) {
            month = -1;
        } else if (type == 2) {
            month = -3;
        } else if (type == 3) {
            month = -6;
        } else if (type == 4) {
            month = -12;
        }

        //1代表为一个月    正的往前  负的为后
        Date date = stepMonth(new Date(), month);

        // 我们去就去查询全部的记录
        List<VisitProduct> list = list();
        if (list == null) {
            return true;
        }
        System.out.println("前一个月时间为" + df.format(date));
        List<Long> collect = list.stream().filter(item -> {
            // 表示这个时间是在这个时间之前的
            return item.getGmtCreate().before(date);
        }).map(VisitProduct::getId).collect(Collectors.toList());


        // 下面进行批量删除
        if (collect.size() == 0) {
            return true;
        }
        boolean b = removeByIds(collect);
        return b;
        // type == 1表示删除1个月前的所有预约记录

        // type == 2表示删除3个月前所有的预约记录

        // type == 3表示删除6个月前所有的预约记录

        // type = 4表示删除1年前所有的预约记录

    }

    /**
     * 删除与productId有关的全部记录
     *
     * @param productId
     */
    @Override
    public void deleteByProductId(Long productId) {
        LambdaQueryWrapper<VisitProduct> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(VisitProduct::getProductId, productId);

        remove(lambdaQueryWrapper);
    }

    public static Date stepMonth(Date sourceDate, int month) {
        Calendar c = Calendar.getInstance();
        c.setTime(sourceDate);
        c.add(Calendar.MONTH, month);
        return c.getTime();
    }


}
